<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>雁过留声</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta property="og:type" content="website">
<meta property="og:title" content="雁过留声">
<meta property="og:url" content="http://yanglf007.gitee.io/blog/page/2/index.html">
<meta property="og:site_name" content="雁过留声">
<meta property="og:locale" content="en_US">
<meta property="article:author" content="yanglf007">
<meta name="twitter:card" content="summary">
  
    <link rel="alternate" href="/blog/atom.xml" title="雁过留声" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  
<link rel="stylesheet" href="/blog/css/style.css">

<meta name="generator" content="Hexo 4.2.0"></head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/blog/" id="logo">雁过留声</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/blog/">Home</a>
        
          <a class="main-nav-link" href="/blog/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/blog/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yanglf007.gitee.io/blog"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-微服务" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/13/%E5%BE%AE%E6%9C%8D%E5%8A%A1/" class="article-date">
  <time datetime="2020-08-13T14:55:57.281Z" itemprop="datePublished">2020-08-13</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/13/%E5%BE%AE%E6%9C%8D%E5%8A%A1/">微服务</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>1.概念<br>超时  调用时间超过一定时长，直接超时错误<br>重试  当一次调用失败时，换服务器重新调用一次<br>熔断  当服务发生异常次数达到一定阈值时，关闭服务，直接返回请求失败<br>限流：防止某个服务qps飙升，限制其并发访问次数<br>服务降级：当服务器压力剧增时，根据优先级提供服务，对低优先级的服务进行降级处理，保证核心任务的正常运行<br>涟漪：A调用B,B调用C,C出现服务抖动，导致A也跟着出现抖动</p>
<p>2 hystrix 熔断原理<br>有三种状态，关闭，开启，半开<br>最开始关闭，所有请求都通过<br>如果请求错误达到一定阈值，就开启状态，所有请求都短路，直接返回失败的响应，<br>一段时间后半开，如果请求成功就开启，否则就关闭<br>hystrix.command.default.circuitBreaker.requestVolumeThreshold（当在配置时间窗口内达到此数量的失败后，进行短路。默认20个）简言之，10s内请求失败数量达到20个，断路器就会变成打开状态。<br>hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds（短路多久以后开始尝试是否恢复，默认5s）<br>hystrix.command.default.circuitBreaker.errorThresholdPercentage（出错百分比阈值，当达到此阈值后，开始短路。默认50%）</p>
<p>熔断原理：</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/13/%E5%BE%AE%E6%9C%8D%E5%8A%A1/" data-id="ckgtnonna000tm8ul5hez8llc" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-netty面试" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/11/netty%E9%9D%A2%E8%AF%95/" class="article-date">
  <time datetime="2020-08-11T15:41:56.669Z" itemprop="datePublished">2020-08-11</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/11/netty%E9%9D%A2%E8%AF%95/">netty面试</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/11/netty%E9%9D%A2%E8%AF%95/" data-id="ckgtnonln0000m8ul3ah8daek" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-tddl面试题" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/11/tddl%E9%9D%A2%E8%AF%95%E9%A2%98/" class="article-date">
  <time datetime="2020-08-11T15:13:24.936Z" itemprop="datePublished">2020-08-11</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/11/tddl%E9%9D%A2%E8%AF%95%E9%A2%98/">tddl面试题</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>tddl架构<br><a href="https://www.cnblogs.com/chenchaochao034/p/11574820.html" target="_blank" rel="noopener">https://www.cnblogs.com/chenchaochao034/p/11574820.html</a></li>
</ol>
<p>主要分三层</p>
<p>matrix 实现分库分表逻辑<br>group 实现数据库的准备切换，读写分离逻辑<br>atom 主要和数据库ip，端口有关，持有原子的数据源</p>
<p>matrix<br>主要通过sql解析，规则计算，表名更换，选择group_data_source执行sql<br>并对atom执行结果进行合并</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/11/tddl%E9%9D%A2%E8%AF%95%E9%A2%98/" data-id="ckgtnonn3000km8ulfbqtd0l8" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-jvm命令" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/11/jvm%E5%91%BD%E4%BB%A4/" class="article-date">
  <time datetime="2020-08-11T12:30:16.418Z" itemprop="datePublished">2020-08-11</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/11/jvm%E5%91%BD%E4%BB%A4/">jvm命令</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>jstat -gcutil pid</p>
<p>线上问题排查<br><a href="https://www.jianshu.com/p/3e54b224a122" target="_blank" rel="noopener">https://www.jianshu.com/p/3e54b224a122</a></p>
<p>jvm 垃圾回收算法<br><a href="https://www.jianshu.com/p/23f8249886c6" target="_blank" rel="noopener">https://www.jianshu.com/p/23f8249886c6</a></p>
<p>1）复制算法<br>2）标记清除算法<br>3）标记整理算法<br>4）分代收集算法<br>5）引用计数算法</p>
<p>新生代收集器：Serial(复制算法)、ParNew(Serial 多线程版本)、Parallel (复制算法多线程版本,关注吞吐量)</p>
<p>老年代收集器：CMS、Serial Old、Parallel Old<br>CMS 初始标记 , 并发标记, 重新标记,并发清除,并发重置<br>STW stop the world 全局暂停现象，全局停顿，所有Java代码停止</p>
<p>整堆收集器： G1 并行与并发的标记-复制垃圾回收器 gradge first 优先级</p>
<h3 id="jvm"><a href="#jvm" class="headerlink" title="jvm"></a>jvm</h3><ol>
<li><p>新生代分几个区，使用什么算法进行回收，为什么使用这个算法</p>
</li>
<li><p>讲一讲垃圾回收器（重点cms、g1），垃圾回收算法<br>cms 使用标记清楚算法，目的是获取最短的停顿时间，提高用户体验<br>初始标记（GC root 直接关联的对象）<br>并发标记（进行GC root跟踪，不暂停）<br>重新标记（暂停，修正并发标记的错误）<br>并发清除</p>
</li>
</ol>
<p>G1 垃圾回收器<br>可以非常精确的控制停顿时间<br>主要针对配备多颗处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征,<br>整体采用“标记—整理”算法，局部（region之间）采用“复制”算法<br>把堆内存分成几个区，跟踪几个区的垃圾回收进度，并且根据允许收集的时间，设置一个优先级列表，优先回收垃圾最多的区域</p>
<ol start="3">
<li><p>如何定位线上的cpu和内存问题（实际操作下）</p>
</li>
<li><p>内存溢出（OOM）和 内存泄漏(memery Leak)-内存没有被回收</p>
</li>
<li><p>JVM 自动内存管理, minorGC 和 Full GC 触发机制<br>Eden内存不够时触发minorGC,对新生代进行垃圾回收，采用复制算法，复制-清空-互换<br>major GC之前一般都进行minor GC，导致新生代对象晋级到老年代，内存不够触发major GC ;major GC采用标记清除算法</p>
</li>
<li><p>JVM调优，基本思路是什么</p>
</li>
<li><p>valatile 关键字如何保证内存可见性和有序性</p>
</li>
</ol>
<ol start="8">
<li><p>jvm中一次完整的GC流程（从ygc到fgc）是怎样的，重点讲讲对象如何晋升到老年代等<br>大对象（需要大量连续内存空间）直接进入老年态；长期存活的对象进入老年态。如果对象在新生代出生并经过第一次MGC后仍然存活，年龄+1，若年龄超过一定限制（15），则被晋升到老年态。</p>
</li>
<li><p>jvm模型</p>
</li>
</ol>
<p><img src="http://chuantu.xyz/t6/740/1596545223x-1922733148.png" alt="avatar"></p>
<p>公共内存 ： 堆，方法区<br>私有：      本地方法栈  程序计数器 虚拟机栈</p>
<p>jvm内存划分<br><img src="http://chuantu.xyz/t6/740/1596548374x1031866013.jpg" alt="avatar"></p>
<p>程序计数器：是当前线程执行字节码行号的指示器，多线程中，线程可能挂起，需要重新找到执行代码的地方,唯一一个无oom的区域<br>本地方法栈：与虚拟机栈相同，一个是存储java方法的相关信息，一个是本地方法<br>虚拟机栈：线程私有，生命周期与线程相同，用来存局部变量，方法出口，每个方法执行的同时会创建一个栈帧，线程结束销毁栈帧，方法执行时一个从入栈到出栈的过程<br>堆：存放在数组中的完全二叉树<br>方法区：保存的是每一个类的信息，保存类的元数据 是Perm Gen（永久代），运行时常量池，1.8时叫元数据区，用的是本地内存</p>
<p>jmap -dump:format=b,file=jmap.dump pid 导出线程<br>可以用jvisualvm 分析,(通过文件-&gt;装入-&gt;选择堆dump)<br>top命令显示的是进程<br>top  -H -p pid 显示的是进程下面的线程</p>
<p>printf ‘%x\n’ pid 可以将10进制转换为</p>
<p>jstack pid | grep ‘nid’ -C10 –color<br>jstack -l 显示长列表 和锁信息<br>jstack -F 当线程挂起时,将堆栈中的信息打印出来</p>
<p>jstat -gc pid 可以查看gc情况</p>
<p>grep </p>
<p>–color    ###颜色着重显示命中的文件及文件件</p>
<p>-n  ###显示行号  number</p>
<p>-i   ###忽略大小写 ignore</p>
<p>-c  ###count统计出现匹配的次数</p>
<p>-E  ###标准posix，支持正则表达式   </p>
<p>grep -E   -v   ‘(^$|^#)’ xxxx   等价于egrep -v ‘(^$|^#)’  xxx<br>-A   n    ###after     前面多少行</p>
<p>-B   n   ###before    后面多少行</p>
<p>-C   n   ###centor    前后多少行</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/11/jvm%E5%91%BD%E4%BB%A4/" data-id="ckgtnonmx000cm8ul1li83274" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-1今日工作" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/10/1%E4%BB%8A%E6%97%A5%E5%B7%A5%E4%BD%9C/" class="article-date">
  <time datetime="2020-08-10T12:55:33.394Z" itemprop="datePublished">2020-08-10</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/10/1%E4%BB%8A%E6%97%A5%E5%B7%A5%E4%BD%9C/">1今日工作</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>mybatis原理</li>
</ol>
<p>1)需要让调用者感知不到调用远程服务<br>2)远程通讯<br>3)序列化反序列化<br>4)服务注册与发现<br>5)负载均衡策略<br>6)通信协议<br>7)服务端线程池<br>8)结果缓存<br>9)多版本控制<br>10)异步调用<br>11)优雅停机<br>        Runtime.getRuntime().addShutdownHook(new MyThread());<br>发送消息通知给订阅方，告知自己下线<br>12)限流容错降级</p>
<ol start="3">
<li><p>dubbo面试题</p>
</li>
<li><p>zookeeper 两种协议</p>
</li>
</ol>
<ol start="5">
<li><p>sql优化部分</p>
</li>
<li><p>docker面试题</p>
</li>
<li><p>学习netty</p>
</li>
</ol>
<p>in 和 exist 什么区别</p>
<p>监听器，过滤器，拦截器</p>
<p>接口加密</p>
<p>并发扩容</p>
<p>kafka与rocketmq区别</p>
<p>redis 协议 resp协议</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/10/1%E4%BB%8A%E6%97%A5%E5%B7%A5%E4%BD%9C/" data-id="ckgtnonlw0002m8ulblcu1v7w" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-dubbo面试" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/10/dubbo%E9%9D%A2%E8%AF%95/" class="article-date">
  <time datetime="2020-08-09T17:49:13.724Z" itemprop="datePublished">2020-08-10</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/10/dubbo%E9%9D%A2%E8%AF%95/">dubbo面试</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>源码分析<br><a href="https://www.jianshu.com/p/0dc2b6a0b270" target="_blank" rel="noopener">https://www.jianshu.com/p/0dc2b6a0b270</a></li>
</ol>
<p>2.dubbo是什么<br>一个基于java的高性能的rpc分布式服务框架</p>
<ol start="3">
<li><p>为什么要用dubbo<br>随着用户增多，单机负载逐渐增多，这是需要业务拆分，满足性能要求，业务直接通过远程调用</p>
</li>
<li><p>Dubbo 和 Spring Cloud 有什么区别？<br>通信方式不同，dubbo基于rpc ，spring cloud基于http restful<br>注册中心      zookeeper      spring cloud eureka<br>spring cloud 组件完善，<br>断路器 netflix Hystrix<br>网关   gateway<br>分布式配置中心 springcloud-config<br>消息总线       springcloud-bus</p>
</li>
<li><p>dubbo 内置了哪几种服务容器<br>spring container<br>jetty container<br>log4j container</p>
</li>
<li><p>Dubbo里面有哪几种节点角色<br>provider<br>customer<br>register  服务主从与发现<br>monitor   统计服务调用次数<br>container 服务运行容器   </p>
</li>
<li><p>负载均衡策略<br>RandomLoadBalance 随机（默认）<br>RoundRobinLoadBalance 轮训<br>ConsistentHashLoadBalance 一致性hash负载<br>LeastActiveLoadBalance 最不活跃</p>
</li>
<li><p>dubbo 核心配置<br>dubbo:protocol<br>dubbo:register<br>dubbo:reference<br>dubbo:application<br>dubbo:service<br>dubbo:monitor<br>dubbo:method<br>dubbo:argument</p>
</li>
<li><p>在 Provider 上可以配置的 Consumer 端的属性有哪些？</p>
</li>
</ol>
<p>1）timeout：方法调用超时<br>2）retries：失败重试次数，默认重试 2 次<br>3）loadbalance：负载均衡算法，默认随机<br>4）actives 消费者端，最大并发调用限制</p>
<p>10 Dubbo推荐使用什么序列化框架，你知道的还有哪些？</p>
<p>推荐使用Hessian序列化，还有Duddo、FastJson、Java自带序列化</p>
<ol start="11">
<li><p>Dubbo默认使用的是什么通信框架，还有别的选择吗？<br>Dubbo 默认使用 Netty 框架</p>
</li>
<li><p>Dubbo有哪几种集群容错方案，默认是哪种？</p>
</li>
</ol>
<p>Failover Cluster，失败自动切换，当出现失败，重试其它服务器。通常用于读操作，但重试会带来更长延迟。<br>Failfast Cluster，快速失败，只发起一次调用，失败立即报错。通常用于非幂等性的写操作，比如新增记录。<br>Failsafe Cluster，失败安全，出现异常时，直接忽略。通常用于写入日志等。<br>Failback Cluster，失败自动恢复，后台记录失败请求，定时重发。通常用于消息通知等。<br>Forking Cluster，并行调用多个服务器，只要一个成功即返回。通常用于实时性要求较高的读操作，但需要浪费更多服务资源。可通过 forks 来设置最大并行数。<br>Broadcast Cluster，广播调用所有提供者，逐个调用，任意一台报错则报错。通常用于通知所有提供者更新缓存本地资源信息。<br>默认 Failover Cluster</p>
<ol start="13">
<li>点对点测试功能<br>配置 dubbo reference 中的url<br>&lt;dubbo:reference id=”xxxService” interface=”com.alibaba.xxx.XxxService” url=”dubbo://localhost:20890” /&gt;</li>
</ol>
<p>然后在映射文件中添加配置xxx.properties，其中key是服务名称，value是服务提供者URL：<br>com.alibaba.xxx.XxxService=dubbo://localhost:20890</p>
<ol start="14">
<li><p>dubbo 接口有多个实现时的配置方案<br>当一个接口有多种实现时，可以用 group 属性来分组，服务提供方和消费方都指定同一个 group 即可。</p>
</li>
<li><p>服务上线怎么兼容旧版本？<br>通过配置版本号 version </p>
</li>
<li><p>如何异步调用</p>
</li>
</ol>
<p>客户端配置</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">dubbo:reference</span> <span class="attr">id</span>=<span class="string">"demoService"</span> <span class="attr">check</span>=<span class="string">"false"</span> <span class="attr">interface</span>=<span class="string">"com.yanglf.springmybatislearn.dubbo.service.DemoService"</span>  &gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">dubbo:method</span> <span class="attr">name</span>=<span class="string">"sayHello"</span> <span class="attr">async</span>=<span class="string">"true"</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">dubbo:reference</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>代码中使用</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Future&lt;String&gt; future = RpcContext.getContext().getFuture();</span><br></pre></td></tr></table></figure>

<ol start="17">
<li>Dubbo的管理控制台能做什么？<br>管理控制台主要包含：路由规则，动态配置，服务降级，访问控制，权重调整，负载均衡，等管理功能。</li>
</ol>
<ol start="18">
<li>dubbo 服务暴露过程</li>
</ol>
<p>com.alibaba.dubbo.config.spring.ServiceBean 实现了ApplicationListener<br>监听ContextRefreshedEvent 事件<br>调用export（）方法，接着调用 doExport（），该方法实现异步发布<br>经过Exchange(com.alibaba.dubbo.remoting.exchange.support.header.HeaderExchanger.bind),<br>Transporter(com.alibaba.dubbo.remoting.Transporters#bind(com.alibaba.dubbo.common.URL, com.alibaba.dubbo.remoting.ChannelHandler…)),<br>最后交个netty</p>
<ol start="19">
<li><p>dubbo spi机制<br>通过接口名称和key值,能获取到接口的具体实现,并且注入到容器中进行管理<br>比如的Protocol和LoadBalance 都是spi机制加载的,默认实现dubbo协议和随机负载均衡,通过 ExtensionLoader加载<br>配置文件在<br>　　META-INF/services/<br>　　META-INF/dubbo/<br>　　META-INF/dubbo/internal/</p>
</li>
<li><p>dubbo和hesion协议有什么不通</p>
</li>
</ol>
<p>dubbo协议 单一长链接,基于nio的异步通信,适合数据量少,消费者比服务者多,不适合传输数据文件<br>http协议  多个短链接,同步,有协议头,数据包混合<br>hessian协议 多个短连接,同步,基于http协议,可以传文件,适合服务提供者多与消费者</p>
<ol start="21">
<li><p>kafka与rocketmq对比<br>数据可靠性<br>kafka只支持异步刷盘<br>rocketmq 可以同步刷盘,也可以异步刷盘,可靠性更高<br>性能<br>kafka单机支持100w tps ,主要原因是productor 可以将多个小消息合并发送到broker<br>rocketmq 单机十几万tps, 不支持消息合并发送<br>队列数<br>kafka 单机队列数64,队列数越多,负载越高<br>rocketmq 单机支持5w队列,负载没什么变化,支持队列越多,可以创建的topic就越多<br>消息投递实时性<br>kafka是短轮询,延时取决于轮询时间<br>rocketmq是长轮询,会有几ms的延时<br>失败重试<br>kafka不支持失败重试<br>rocketmq可以失败重试,重试默认16次,重试间隔时间依次增加<br>顺序消费<br>kafka支持顺序消费<br>rocketmq,资产同一个broker的顺序消费,想要全局的顺序性<br>定时消息<br>kafka不支持定时消息<br>rocketmq支持定时消息<br>消息查询<br>kafka 不支持消息查询<br>rocketmq 支持messageId 和 message key查询<br>消息过滤<br>kafka不支持消息过滤<br>rocketmq支持消费短根据tag进行消息过滤,相当于2级topic</p>
</li>
<li><p>消息堆积怎么处理</p>
</li>
<li><p>rocketmq消息重试机制是什么原理</p>
</li>
</ol>
<p>rpc主要考虑哪些问题<br> 1,透明化调用<br> 2,远程通信协议<br> 3,注册中心,服务发现与注册<br> 4,远程通信<br> 5,序列化反序列化<br> 6,长链接还是短链接<br> 7,负载均衡<br> 8,结果缓存<br> 9,多版本控制<br> 10,异步调用<br> 11,优雅停机<br> 12,集成spring</p>
<p>dubbo如何试下并发控制</p>
<p>ExecuteLimitFilter,通过信号量Semaphore,如果信号量不存在,则创建一个,tryAcquire()获取不到就报错</p>
<p>如何做到限流<br>TpsLimitFilter<br>原理是滑动窗口</p>
<p>dubbo 服务暴露过程<br>ServiceBean 监听ApplicationEvent事件<br>调用export方法 是 serviceConfig的方法<br>里面会有调用 doExportUrls<br>根据配置文件，组装一个url,根据本地暴露还是远程暴露，组装不同的url</p>
<p>无注册中心：dubbo://192.168.3.19:20880/xxxx<br>有注册中心：registry://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=provider&amp;dubbo=2.0.2&amp;export=dubbo://192.168.3.19:20880/xxxx</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/10/dubbo%E9%9D%A2%E8%AF%95/" data-id="ckgtnonlx0003m8ul80zwadr0" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-mybatis面试" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/09/mybatis%E9%9D%A2%E8%AF%95/" class="article-date">
  <time datetime="2020-08-09T09:30:46.756Z" itemprop="datePublished">2020-08-09</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/09/mybatis%E9%9D%A2%E8%AF%95/">mybatis面试</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>mybatis原理<br>jdk 动态代理</li>
</ol>
<p>jdbc查询数据步骤</p>
<p>1.加载数据库驱动<br>2. 使用jdbc链接数据库<br>3. 通过连接 conn.和sql 创建prepareStatement<br>4. prepareStatement向数据库发出sql 并且返回resultSet<br>5</p>
<p>org.mybatis.spring.mapper.MapperFactoryBean 实现 FactoryBean<br>getObject()<br>getObjectType()<br>isSingleton()</p>
<p>1.MapperProxyFactory 通过newInstance（ClassLoader loader,Class&lt;?&gt;[] interfaces,InvocationHandler h）方法创建代理对象<br>sqlSessionTemplate getMapper的时候调用</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line">org.mybatis.spring.mapper.MapperFactoryBean 实现 FactoryBean</span><br><span class="line">getObject()</span><br><span class="line">getObjectType()</span><br><span class="line">isSingleton()</span><br><span class="line"></span><br><span class="line">getSqlSession().getMapper(<span class="keyword">this</span>.mapperInterface);</span><br><span class="line">configuration.getMapper(type, <span class="keyword">this</span>);</span><br><span class="line">mapperRegistry.getMapper(type, sqlSession);</span><br><span class="line">org.apache.ibatis.binding.MapperRegistry#getMapper //最终调用 工厂创建bean的地方</span><br><span class="line"></span><br><span class="line">```org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.binding.MapperProxy&lt;T&gt;)</span><br><span class="line"><span class="number">2</span>.MapperProxy implements InvocationHandler</span><br><span class="line"><span class="number">3</span>.调用方法的时候，实际上调用的是MapperProxy invoke</span><br><span class="line"></span><br><span class="line"><span class="number">4</span> 根据查询还是更新和返回结果 调用sqlSession的select方法,defaultSqlSession 的方法 selectList</span><br><span class="line"></span><br><span class="line"><span class="number">5</span>. 通过类名和方法名 从配置中找到MappedStatement</span><br><span class="line"><span class="number">6</span>. 解析sql 绑定查询参数</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> Mybatis 的一级缓存原理 的一级缓存原理 （ sqlsession 级别 ） ）</span><br><span class="line">第一次发出一个查询 sql，sql 查询结果写入 sqlsession 的一级缓存中，缓存使用的数据结构是一个 map。</span><br><span class="line">key：MapperID+offset+limit+Sql+所有的入参</span><br><span class="line">value：用户信息</span><br><span class="line">同一个 sqlsession 再次发出相同的 sql，就从缓存中取出数据。如果两次中间出现 commit 操作</span><br><span class="line">（修改、添加、删除），本 sqlsession 中的一级缓存区域全部清空，下次再去缓存中查询不到所</span><br><span class="line">以要从数据库查询，从数据库查询到再写入缓存</span><br><span class="line"></span><br><span class="line">```java</span><br><span class="line">    CacheKey cacheKey = <span class="keyword">new</span> CacheKey();</span><br><span class="line">    cacheKey.update(ms.getId());</span><br><span class="line">    cacheKey.update(rowBounds.getOffset());</span><br><span class="line">    cacheKey.update(rowBounds.getLimit());</span><br><span class="line">    cacheKey.update(boundSql.getSql());</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/09/mybatis%E9%9D%A2%E8%AF%95/" data-id="ckgtnonmz000em8ul0ta5cq0s" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-spring面试" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/09/spring%E9%9D%A2%E8%AF%95/" class="article-date">
  <time datetime="2020-08-09T05:23:04.017Z" itemprop="datePublished">2020-08-09</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/09/spring%E9%9D%A2%E8%AF%95/">spring面试</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li><p>spring ioc容器初始化过程</p>
</li>
<li><p>一个http请求的处理</p>
</li>
<li><p>自定义一个springboot-starter</p>
<p> 分三步</p>
<ol>
<li><p>pom.xml 文件中引入 spring-boot-autoconfigure </p>
</li>
<li><p>meta-inf 创建spring.factories 并配置EnableAutoConfiguration 路径</p>
</li>
<li><p>创建需要自动装配的类，在配置类中可以注册其他需要的service Bean</p>
<p>原理：</p>
</li>
<li><p>@springbootApplication 注解中包含一个@EnableAutoConfiguration注解，</p>
</li>
<li><p>@EnableAutoConfiguration 注解会用@Import 注入一个AutoConfigurationImportSelector 类</p>
</li>
<li><p>importSelector 类中有个方法selectImports（），会调用getAutoConfigurationEntry（），这个类会获取所有配置的enableAutoConfiguration类，<br>然后注入到spring容器中</p>
</li>
</ol>
</li>
<li><p>autowaried自动注入原理</p>
</li>
</ol>
<p>5.@springbootApplication 注解作用<br>该注解主要包含三个注解 @ComponentScan，@SpringBootConfiguration，@EnableAutoConfiguration<br>@ComponentScan 扫描启动类下包和子包具有 @Service,@Component,@Controller注解的类<br>@SpringBootConfiguration 表明启动类是一个配置类，可以在里面注册bean<br>@EnableAutoConfiguration 扫描所在的类 一般会在自定义starter中在spring.factories配置</p>
<ol start="6">
<li>spring 容器初始化过程</li>
</ol>
<p>public void refresh() throws BeansException, IllegalStateException {<br>synchronized (this.startupShutdownMonitor) {<br>// 1. 初始化 refresh 的上下文环境<br>this.prepareRefresh();</p>
<p>// 2. 初始化 BeanFactory，加载并解析配置<br>ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();</p>
<p>/* —至此，已经完成了简单容器的所有功能，下面开始对简单容器进行增强— */</p>
<p>// 3. 对 BeanFactory 进行功能增强<br>this.prepareBeanFactory(beanFactory);</p>
<p>try {<br>// 4. 后置处理 beanFactory，交由子类实现<br>this.postProcessBeanFactory(beanFactory);</p>
<p>// 5. 调用已注册的 BeanFactoryPostProcessor<br>this.invokeBeanFactoryPostProcessors(beanFactory);</p>
<p>// 6. 注册 BeanPostProcessor，仅仅是注册，调用在getBean的时候<br>this.registerBeanPostProcessors(beanFactory);</p>
<p>// 7. 初始化国际化资源<br>this.initMessageSource();</p>
<p>// 8. 初始化事件广播器<br>this.initApplicationEventMulticaster();</p>
<p>// 9. 留给子类实现的模板方法<br>this.onRefresh();</p>
<p>// 10. 注册事件监听器<br>this.registerListeners();</p>
<p>// 11. 实例化所有非延迟加载的单例<br>this.finishBeanFactoryInitialization(beanFactory);</p>
<p>// 12. 完成刷新过程，发布应用事件<br>this.finishRefresh();</p>
<p>springbean 生命周期</p>
<p>InstantiationAwareBeanPostProcessor createBean<br>一. 实例化<br>从xml读取bean配置到Resource中,将resource解析成BeanDefinition<br>利用构造方法和反射,实例化bean,并包装成BeanWrapper,</p>
<p>二. 属性赋值</p>
<p>三. 初始化</p>
<p>四. 销毁</p>
<p>spring 三级缓存<br><a href="https://www.jianshu.com/p/ed58e788639d" target="_blank" rel="noopener">https://www.jianshu.com/p/ed58e788639d</a></p>
<p>aop原理<br>org.springframework.aop.framework.JdkDynamicAopProxy</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/09/spring%E9%9D%A2%E8%AF%95/" data-id="ckgtnonn5000nm8ularu3ftlz" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-java命令" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/06/java%E5%91%BD%E4%BB%A4/" class="article-date">
  <time datetime="2020-08-05T16:11:35.103Z" itemprop="datePublished">2020-08-06</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/06/java%E5%91%BD%E4%BB%A4/">java命令</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>javac 编译<br>javap  -verbose 查看字节码文件</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/06/java%E5%91%BD%E4%BB%A4/" data-id="ckgtnonmu0008m8ul89k16z04" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  
    <article id="post-happen-before原则" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/blog/2020/08/04/happen-before%E5%8E%9F%E5%88%99/" class="article-date">
  <time datetime="2020-08-04T13:21:38.746Z" itemprop="datePublished">2020-08-04</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/blog/2020/08/04/happen-before%E5%8E%9F%E5%88%99/">happen-before原则</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p>happens-before：<br>如果一个操作执行的结果需要对另一个操作可见，那么这两个操作必须存在happens-befores关系</p>
<p>程序次序规则：在一个单独的线程中，按照程序代码的执行流顺序，（时间上）先执行的操作happen—before（时间上）后执行的操作<br>管理锁定规则：一个unlock操作happen—before后面（时间上的先后顺序，下同）对同一个锁的lock操作<br>volatile变量规则：对一个volatile变量的写操作happen—before后面对该变量的读操作<br>线程启动规则：Thread对象的start（）方法happen—before此线程的每一个动作<br>线程终止规则：线程的所有操作都happen—before对此线程的终止检测，可以通过Thread.join（）方法结束、Thread.isAlive（）的返回值等手段检测到线程已经终止执行<br>线程中断规则：对线程interrupt（）方法的调用happen—before发生于被中断线程的代码检测到中断时事件的发生<br>对象终结规则：一个对象的初始化完成（构造函数执行结束）happen—before它的finalize（）方法的开始<br>传递性：如果操作A happen—before操作B，操作B happen—before操作C，那么可以得出A happen—before操作C</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yanglf007.gitee.io/blog/2020/08/04/happen-before%E5%8E%9F%E5%88%99/" data-id="ckgtnonmv0009m8ul7ox2h3gp" class="article-share-link">Share</a>
      
      
    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    
    <a class="extend prev" rel="prev" href="/blog/">&amp;laquo; Prev</a><a class="page-number" href="/blog/">1</a><span class="page-number current">2</span><a class="page-number" href="/blog/page/3/">3</a><a class="page-number" href="/blog/page/4/">4</a><a class="extend next" rel="next" href="/blog/page/3/">Next &amp;raquo;</a>
  </nav>

</section>
        
          <aside id="sidebar">
  
    

  
    

  
    
  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/10/">October 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/08/">August 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/07/">July 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/06/">June 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/05/">May 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/04/">April 2020</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/blog/2020/10/25/%E6%AF%8F%E6%97%A5%E5%AD%A6%E4%B9%A0/">每日学习</a>
          </li>
        
          <li>
            <a href="/blog/2020/10/12/mybatis-plus/">mybatis-plus</a>
          </li>
        
          <li>
            <a href="/blog/2020/08/30/%E7%A7%92%E6%9D%80%E7%B3%BB%E7%BB%9F/">秒杀系统</a>
          </li>
        
          <li>
            <a href="/blog/2020/08/29/elasticsearch%E7%9F%A5%E8%AF%86/">elasticsearch知识</a>
          </li>
        
          <li>
            <a href="/blog/2020/08/28/redis%E9%9D%A2%E8%AF%95/">redis面试</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2020 yanglf007<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/blog/" class="mobile-nav-link">Home</a>
  
    <a href="/blog/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  
<link rel="stylesheet" href="/blog/fancybox/jquery.fancybox.css">

  
<script src="/blog/fancybox/jquery.fancybox.pack.js"></script>




<script src="/blog/js/script.js"></script>




  </div>
</body>
</html>